package com.foryou.wechat.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.foryou.wechat.common.Constants;
import com.foryou.wechat.common.enums.MessageEnum;
import com.foryou.wechat.entity.ChatDetailEntity;
import com.foryou.wechat.entity.ChatEntity;
import com.foryou.wechat.entity.ChatListEntity;
import com.foryou.wechat.mapper.ChatDetailMapper;
import com.foryou.wechat.mapper.ChatListMapper;
import com.foryou.wechat.mapper.ChatMapper;
import com.foryou.wechat.model.vo.ChatDetailVo;
import com.foryou.wechat.model.vo.ChatItemVo;
import com.foryou.wechat.model.vo.FileVo;
import com.foryou.wechat.service.ChatService;
import com.foryou.wechat.service.UserService;
import com.foryou.wechat.utils.FileUtil;
import com.foryou.wechat.utils.HttpContextUtils;
import com.foryou.wechat.utils.RelativeDateFormat;
import com.foryou.wechat.utils.Response;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.springframework.web.multipart.MultipartFile;

import java.util.Date;
import java.util.List;

/**
 * Created by Lee.
 */
@Service
public class ChatServiceImpl implements ChatService {

    private final ChatMapper chatMapper;

    private final ChatDetailMapper chatDetailMapper;

    private final ChatListMapper chatListMapper;

    private final UserService userService;

    @Value("${web.upload}")
    private String uploadPrefix;

    @Value("${web.url}")
    private String url;

    public ChatServiceImpl(ChatMapper chatMapper, ChatDetailMapper chatDetailMapper, ChatListMapper chatListMapper, UserService userService) {
        this.chatMapper = chatMapper;
        this.chatDetailMapper = chatDetailMapper;
        this.chatListMapper = chatListMapper;
        this.userService = userService;
    }

    @Override
    public Response getChatList(Long userId,int start) {
        List<ChatItemVo> chatList = chatListMapper.getChatList(userId, start);
        chatList.forEach(e->{
            ChatDetailEntity lastedDetail = chatDetailMapper.getLastedDetail(e.getChatId());
            String content = "暂无最新消息";
            if (!ObjectUtils.isEmpty(lastedDetail)) {
                content = lastedDetail.getType()==0?lastedDetail.getContent():"媒体消息请打开后查看";
            }
            e.setContent(content);
            e.setTime(RelativeDateFormat.format(e.getCreateTime()));
        });
        return Response.success(chatList);
    }

    @Override
    public boolean isFirstChat(Long anotherId) {
        Long userId = HttpContextUtils.getUserId();
        ChatEntity chatEntity = chatMapper.selectOne(new QueryWrapper<ChatEntity>()
                .eq("user_id", userId)
                .eq("another_id", anotherId)
        );
        return !ObjectUtils.isEmpty(chatEntity);
    }

    @Override
    @Transactional
    public Response openChatWindow(Long anotherId) {
        Long userId = HttpContextUtils.getUserId();
        ChatEntity chatEntity = chatMapper.selectOne(new QueryWrapper<ChatEntity>()
                .eq("user_id", userId)
                .eq("another_id", anotherId)
        );
        if (ObjectUtils.isEmpty(chatEntity)) {
            //1.在主表创建一条记录
            chatEntity = new ChatEntity(userId, anotherId);
            int result = chatMapper.insert(chatEntity);
            if (result < 0) {
                throw new RuntimeException(Constants.OPERATION_FAILURE);
            }
            //2.在聊天列表表里面创建两条记录
            chatListMapper.insert(new ChatListEntity(chatEntity.getId(), userId, anotherId,0));
            chatListMapper.insert(new ChatListEntity(chatEntity.getId(), anotherId, userId,1));
        }else {
            this.onlineOrOffline(userId, chatEntity.getId());
        }
        JSONObject map = new JSONObject();
        map.put("chatLog", chatDetailMapper.getChatDetailInfo(chatEntity.getId()));
        map.put("chatId", chatEntity.getId());
        map.put("user", userService.getUserInfo(userId).getData());
        return Response.success(map);
    }

    @Override
    public Response getUserChatLog(Long chatId) {
        List<ChatDetailVo> detailInfo = chatDetailMapper.getChatDetailInfo(chatId);
        return Response.success(detailInfo);
    }

    @Override
    @Transactional
    public Response sendTextMessage(Long chatId, String content) {
        beforeInsertLog(HttpContextUtils.getUserId(),chatId);
        chatDetailMapper.insert(new ChatDetailEntity(chatId, HttpContextUtils.getUserId(), content,"",MessageEnum.TEXT.getCode()));
        return Response.success();
    }

    @Override
    @Transactional
    public Response sendAudioMessage(Long chatId,String duration,MultipartFile file) {
        beforeInsertLog(HttpContextUtils.getUserId(),chatId);
        return sendMediaMessage(chatId,duration,file,MessageEnum.AUDIO);
    }

    @Override
    public Response sendImageMessage(Long chatId, MultipartFile file) {
        beforeInsertLog(HttpContextUtils.getUserId(),chatId);
        return sendMediaMessage(chatId,"",file,MessageEnum.IMAGE);
    }

    @Override
    public Response onlineOrOffline(Long userId, Long chatId) {
        ChatListEntity chatListEntity = chatListMapper.selectOne(new QueryWrapper<ChatListEntity>()
                .eq("chat_id", chatId)
                .eq("user_id",userId)
        );
        if (!ObjectUtils.isEmpty(chatListEntity)) {
            int online = chatListEntity.getIsOnline() == 0 ? 1 : 0;
            chatListEntity.setIsOnline(online);
            chatListMapper.updateById(chatListEntity);
        }
        return Response.success();
    }

    @Transactional
    protected Response sendMediaMessage(Long chatId,String duration, MultipartFile file, MessageEnum messageEnum) {
        Long userId = HttpContextUtils.getUserId();
        beforeInsertLog(userId,chatId);
        String content = "";
        //上传媒体文件到服务器
        try {
            content = uploadMediaFile(userId, file);
        } catch (Exception e) {
            e.printStackTrace();
        }
        chatDetailMapper.insert(new ChatDetailEntity(chatId, userId, content,duration,messageEnum.getCode()));
        return Response.success(content);
    }

    @Override
    public Response removeList(Long chatId, Long userId) {

        int result = chatListMapper.delete(new QueryWrapper<ChatListEntity>()
                .eq("chat_id",chatId)
                .eq("user_id",userId)
        );

        return result>0?Response.success():Response.failure(Constants.OPERATION_FAILURE);
    }

    @Transactional
    protected void beforeInsertLog(Long userId,Long chatId) {
        ChatListEntity chatListEntity = chatListMapper.selectOne(new QueryWrapper<ChatListEntity>()
                .eq("chat_id", chatId)
                .eq("another_id",userId)
        );
        //如果不在线
        if (chatListEntity.getIsOnline() == 1){
            chatListEntity.setUnread(chatListEntity.getUnread()+1);
            chatListMapper.updateById(chatListEntity);
        }
        ChatDetailEntity lastedDetail = chatDetailMapper.getLastedDetail(chatId);
        if (!ObjectUtils.isEmpty(lastedDetail)) {
            lastedDetail.setIsLatest(0);
            chatDetailMapper.updateById(lastedDetail);
        }
    }

    private String uploadMediaFile(Long userId,MultipartFile file) throws Exception{
        // /userId/File/2019-10
        String folderName = String.valueOf(userId)
                    .concat("/File/")
                    .concat(DateFormatUtils.format(new Date(), Constants.DATE_FORMAT_PATTERN2)
                    .concat("/")
        );
        FileVo fileVo = FileUtil.uploadFile(uploadPrefix.concat(folderName), file);
        String dataUrl = url + folderName + fileVo.getFileName();
        return dataUrl;
    }
}
